/**
 * 设备管理增强服务
 * 处理设备绑定、报修、维护等业务逻辑
 */

const Parse = require('parse/node');

class DeviceService {
    /**
     * 获取设备列表
     * @param {Object} options - 查询选项
     * @returns {Promise<Object>} 设备列表和分页信息
     */
    static async getDevices(options = {}) {
        const {
            page = 1,
            pageSize = 10,
            search = '',
            status = '',
            userId = '',
            category = ''
        } = options;

        const Device = Parse.Object.extend('Device');
        const query = new Parse.Query(Device);

        // 添加筛选条件
        if (search) {
            const searchQueries = [
                new Parse.Query(Device).contains('name', search),
                new Parse.Query(Device).contains('code', search),
                new Parse.Query(Device).contains('model', search)
            ];
            query._orQuery(searchQueries);
        }

        if (status) {
            query.equalTo('status', status);
        }

        if (userId) {
            const User = Parse.Object.extend('_User');
            const user = new User();
            user.id = userId;
            query.equalTo('bindUser', user);
        }

        if (category) {
            query.equalTo('category', category);
        }

        // 关联查询
        query.include(['bindUser', 'lastUser']);

        // 分页
        const total = await query.count();
        query.skip((page - 1) * pageSize);
        query.limit(pageSize);
        query.descending('createdAt');

        const devices = await query.find();

        return {
            data: devices.map(device => ({
                id: device.id,
                name: device.get('name'),
                code: device.get('code'),
                model: device.get('model'),
                category: device.get('category'),
                status: device.get('status'),
                location: device.get('location'),
                qrCode: device.get('qrCode'),
                bindUser: device.get('bindUser') ? {
                    id: device.get('bindUser').id,
                    username: device.get('bindUser').get('username'),
                    name: device.get('bindUser').get('name') || device.get('bindUser').get('username')
                } : null,
                bindTime: device.get('bindTime'),
                lastUsed: device.get('lastUsed'),
                description: device.get('description'),
                createdAt: device.get('createdAt'),
                updatedAt: device.get('updatedAt')
            })),
            total,
            page,
            pageSize,
            totalPages: Math.ceil(total / pageSize)
        };
    }

    /**
     * 绑定设备
     * @param {Object} bindData - 绑定数据
     * @returns {Promise<Object>} 绑定结果
     */
    static async bindDevice(bindData) {
        const {
            userId,
            deviceCode,
            deviceName,
            deviceModel,
            location,
            remark
        } = bindData;

        // 验证用户
        const User = Parse.Object.extend('_User');
        const userQuery = new Parse.Query(User);
        const user = await userQuery.get(userId);
        if (!user) {
            throw new Error('用户不存在');
        }

        // 检查设备是否已存在
        const Device = Parse.Object.extend('Device');
        const deviceQuery = new Parse.Query(Device);
        deviceQuery.equalTo('code', deviceCode);
        const existingDevice = await deviceQuery.first();

        let device;
        if (existingDevice) {
            // 设备已存在，更新绑定信息
            if (existingDevice.get('bindUser') && existingDevice.get('status') === 'active') {
                throw new Error('设备已被其他用户绑定');
            }
            device = existingDevice;
        } else {
            // 创建新设备
            device = new Device();
            device.set('code', deviceCode);
            device.set('name', deviceName);
            device.set('model', deviceModel);
            device.set('qrCode', `DEVICE_${deviceCode}_${Date.now()}`);
            device.set('category', '通用设备');
        }

        // 设置绑定信息
        device.set('bindUser', user);
        device.set('status', 'active');
        device.set('location', location);
        device.set('bindTime', new Date());
        device.set('lastUsed', new Date());
        device.set('description', remark);

        const savedDevice = await device.save();

        // 记录操作日志
        await this.createDeviceLog({
            deviceId: savedDevice.id,
            userId: userId,
            action: 'bind',
            description: `用户绑定设备: ${deviceName} (${deviceCode})`
        });

        return {
            id: savedDevice.id,
            name: savedDevice.get('name'),
            code: savedDevice.get('code'),
            model: savedDevice.get('model'),
            status: savedDevice.get('status'),
            location: savedDevice.get('location'),
            qrCode: savedDevice.get('qrCode'),
            bindTime: savedDevice.get('bindTime')
        };
    }

    /**
     * 扫码绑定设备
     * @param {Object} scanData - 扫码数据
     * @returns {Promise<Object>} 绑定结果
     */
    static async scanBindDevice(scanData) {
        const { userId, qrCode } = scanData;

        // 验证用户
        const User = Parse.Object.extend('_User');
        const userQuery = new Parse.Query(User);
        const user = await userQuery.get(userId);
        if (!user) {
            throw new Error('用户不存在');
        }

        // 根据二维码查找设备
        const Device = Parse.Object.extend('Device');
        const deviceQuery = new Parse.Query(Device);
        deviceQuery.equalTo('qrCode', qrCode);
        const device = await deviceQuery.first();

        if (!device) {
            throw new Error('设备不存在或二维码无效');
        }

        if (device.get('bindUser') && device.get('status') === 'active') {
            throw new Error('设备已被其他用户绑定');
        }

        // 绑定设备
        device.set('bindUser', user);
        device.set('status', 'active');
        device.set('bindTime', new Date());
        device.set('lastUsed', new Date());

        const savedDevice = await device.save();

        // 记录操作日志
        await this.createDeviceLog({
            deviceId: savedDevice.id,
            userId: userId,
            action: 'scan_bind',
            description: `用户扫码绑定设备: ${device.get('name')} (${device.get('code')})`
        });

        return {
            id: savedDevice.id,
            name: savedDevice.get('name'),
            code: savedDevice.get('code'),
            model: savedDevice.get('model'),
            status: savedDevice.get('status'),
            location: savedDevice.get('location'),
            qrCode: savedDevice.get('qrCode'),
            bindTime: savedDevice.get('bindTime')
        };
    }

    /**
     * 解绑设备
     * @param {string} deviceId - 设备ID
     * @param {string} userId - 用户ID
     * @returns {Promise<Object>} 解绑结果
     */
    static async unbindDevice(deviceId, userId) {
        const Device = Parse.Object.extend('Device');
        const query = new Parse.Query(Device);
        const device = await query.get(deviceId);

        if (!device) {
            throw new Error('设备不存在');
        }

        if (!device.get('bindUser') || device.get('bindUser').id !== userId) {
            throw new Error('无权解绑此设备');
        }

        // 解绑设备
        device.set('bindUser', null);
        device.set('status', 'idle');
        device.set('unbindTime', new Date());

        const savedDevice = await device.save();

        // 记录操作日志
        await this.createDeviceLog({
            deviceId: deviceId,
            userId: userId,
            action: 'unbind',
            description: `用户解绑设备: ${device.get('name')} (${device.get('code')})`
        });

        return {
            id: savedDevice.id,
            status: savedDevice.get('status'),
            unbindTime: savedDevice.get('unbindTime')
        };
    }

    /**
     * 提交设备报修
     * @param {Object} repairData - 报修数据
     * @returns {Promise<Object>} 报修结果
     */
    static async submitRepair(repairData) {
        const {
            deviceId,
            userId,
            problem,
            priority,
            images,
            contact
        } = repairData;

        // 验证设备
        const Device = Parse.Object.extend('Device');
        const deviceQuery = new Parse.Query(Device);
        const device = await deviceQuery.get(deviceId);

        if (!device) {
            throw new Error('设备不存在');
        }

        // 验证用户
        const User = Parse.Object.extend('_User');
        const userQuery = new Parse.Query(User);
        const user = await userQuery.get(userId);

        if (!user) {
            throw new Error('用户不存在');
        }

        // 创建报修记录
        const RepairRecord = Parse.Object.extend('RepairRecord');
        const repair = new RepairRecord();

        repair.set('device', device);
        repair.set('reporter', user);
        repair.set('problem', problem);
        repair.set('priority', priority);
        repair.set('status', 'pending');
        repair.set('images', images || []);
        repair.set('contact', contact);
        repair.set('submitTime', new Date());

        // 设置预期完成时间
        const expectedTime = new Date();
        switch (priority) {
            case 'urgent':
                expectedTime.setHours(expectedTime.getHours() + 4);
                break;
            case 'high':
                expectedTime.setDate(expectedTime.getDate() + 1);
                break;
            case 'medium':
                expectedTime.setDate(expectedTime.getDate() + 3);
                break;
            default:
                expectedTime.setDate(expectedTime.getDate() + 7);
        }
        repair.set('expectedTime', expectedTime);

        const savedRepair = await repair.save();

        // 更新设备状态
        device.set('status', 'repairing');
        await device.save();

        // 记录操作日志
        await this.createDeviceLog({
            deviceId: deviceId,
            userId: userId,
            action: 'repair_submit',
            description: `用户提交设备报修: ${problem}`
        });

        return {
            id: savedRepair.id,
            deviceId: deviceId,
            deviceName: device.get('name'),
            deviceCode: device.get('code'),
            problem: problem,
            priority: priority,
            status: 'pending',
            submitTime: savedRepair.get('submitTime'),
            expectedTime: savedRepair.get('expectedTime')
        };
    }

    /**
     * 获取报修记录
     * @param {Object} options - 查询选项
     * @returns {Promise<Object>} 报修记录列表
     */
    static async getRepairRecords(options = {}) {
        const {
            page = 1,
            pageSize = 10,
            userId = '',
            deviceId = '',
            status = ''
        } = options;

        const RepairRecord = Parse.Object.extend('RepairRecord');
        const query = new Parse.Query(RepairRecord);

        // 添加筛选条件
        if (userId) {
            const User = Parse.Object.extend('_User');
            const user = new User();
            user.id = userId;
            query.equalTo('reporter', user);
        }

        if (deviceId) {
            const Device = Parse.Object.extend('Device');
            const device = new Device();
            device.id = deviceId;
            query.equalTo('device', device);
        }

        if (status) {
            query.equalTo('status', status);
        }

        // 关联查询
        query.include(['device', 'reporter', 'handler']);

        // 分页
        const total = await query.count();
        query.skip((page - 1) * pageSize);
        query.limit(pageSize);
        query.descending('createdAt');

        const repairs = await query.find();

        return {
            data: repairs.map(repair => ({
                id: repair.id,
                deviceId: repair.get('device').id,
                deviceName: repair.get('device').get('name'),
                deviceCode: repair.get('device').get('code'),
                reporter: {
                    id: repair.get('reporter').id,
                    username: repair.get('reporter').get('username'),
                    name: repair.get('reporter').get('name') || repair.get('reporter').get('username')
                },
                problem: repair.get('problem'),
                priority: repair.get('priority'),
                status: repair.get('status'),
                images: repair.get('images') || [],
                contact: repair.get('contact'),
                submitTime: repair.get('submitTime'),
                expectedTime: repair.get('expectedTime'),
                handler: repair.get('handler') ? {
                    id: repair.get('handler').id,
                    username: repair.get('handler').get('username'),
                    name: repair.get('handler').get('name') || repair.get('handler').get('username')
                } : null,
                handlerNote: repair.get('handlerNote'),
                completedTime: repair.get('completedTime'),
                solution: repair.get('solution'),
                createdAt: repair.get('createdAt'),
                updatedAt: repair.get('updatedAt')
            })),
            total,
            page,
            pageSize,
            totalPages: Math.ceil(total / pageSize)
        };
    }

    /**
     * 处理报修
     * @param {string} repairId - 报修ID
     * @param {Object} handleData - 处理数据
     * @returns {Promise<Object>} 处理结果
     */
    static async handleRepair(repairId, handleData) {
        const {
            handlerId,
            action,
            note,
            solution
        } = handleData;

        // 获取报修记录
        const RepairRecord = Parse.Object.extend('RepairRecord');
        const query = new Parse.Query(RepairRecord);
        query.include(['device', 'reporter']);
        const repair = await query.get(repairId);

        if (!repair) {
            throw new Error('报修记录不存在');
        }

        // 获取处理人
        const User = Parse.Object.extend('_User');
        const handlerQuery = new Parse.Query(User);
        const handler = await handlerQuery.get(handlerId);

        if (!handler) {
            throw new Error('处理人不存在');
        }

        // 更新报修记录
        repair.set('handler', handler);
        repair.set('handlerNote', note);
        repair.set('status', action);

        if (action === 'completed') {
            repair.set('completedTime', new Date());
            repair.set('solution', solution);
            
            // 更新设备状态
            const device = repair.get('device');
            device.set('status', 'active');
            await device.save();
        } else if (action === 'processing') {
            // 设备保持维修状态
            const device = repair.get('device');
            device.set('status', 'repairing');
            await device.save();
        }

        const savedRepair = await repair.save();

        // 记录操作日志
        await this.createDeviceLog({
            deviceId: repair.get('device').id,
            userId: handlerId,
            action: `repair_${action}`,
            description: `处理设备报修: ${action} - ${note}`
        });

        return {
            id: savedRepair.id,
            status: action,
            handler: {
                id: handler.id,
                username: handler.get('username'),
                name: handler.get('name') || handler.get('username')
            },
            handlerNote: note,
            completedTime: savedRepair.get('completedTime'),
            solution: solution
        };
    }

    /**
     * 获取设备统计数据
     * @returns {Promise<Object>} 统计数据
     */
    static async getDeviceStats() {
        const Device = Parse.Object.extend('Device');
        
        // 总设备数
        const totalQuery = new Parse.Query(Device);
        const total = await totalQuery.count();

        // 在用设备数
        const activeQuery = new Parse.Query(Device);
        activeQuery.equalTo('status', 'active');
        const active = await activeQuery.count();

        // 空闲设备数
        const idleQuery = new Parse.Query(Device);
        idleQuery.equalTo('status', 'idle');
        const idle = await idleQuery.count();

        // 维修设备数
        const repairingQuery = new Parse.Query(Device);
        repairingQuery.equalTo('status', 'repairing');
        const repairing = await repairingQuery.count();

        // 损坏设备数
        const brokenQuery = new Parse.Query(Device);
        brokenQuery.equalTo('status', 'broken');
        const broken = await brokenQuery.count();

        // 报修统计
        const RepairRecord = Parse.Object.extend('RepairRecord');
        const pendingRepairQuery = new Parse.Query(RepairRecord);
        pendingRepairQuery.equalTo('status', 'pending');
        const pendingRepairs = await pendingRepairQuery.count();

        const processingRepairQuery = new Parse.Query(RepairRecord);
        processingRepairQuery.equalTo('status', 'processing');
        const processingRepairs = await processingRepairQuery.count();

        return {
            total,
            active,
            idle,
            repairing,
            broken,
            pendingRepairs,
            processingRepairs,
            utilizationRate: total > 0 ? (active / total * 100).toFixed(1) : 0,
            repairRate: total > 0 ? (repairing / total * 100).toFixed(1) : 0
        };
    }

    /**
     * 创建设备操作日志
     * @param {Object} logData - 日志数据
     * @returns {Promise<Object>} 创建的日志
     */
    static async createDeviceLog(logData) {
        const {
            deviceId,
            userId,
            action,
            description
        } = logData;

        const DeviceLog = Parse.Object.extend('DeviceLog');
        const log = new DeviceLog();

        log.set('deviceId', deviceId);
        log.set('userId', userId);
        log.set('action', action);
        log.set('description', description);
        log.set('createdAt', new Date());

        return await log.save();
    }

    /**
     * 获取设备操作日志
     * @param {Object} options - 查询选项
     * @returns {Promise<Object>} 操作日志列表
     */
    static async getDeviceLogs(options = {}) {
        const {
            page = 1,
            pageSize = 10,
            deviceId = '',
            userId = '',
            action = ''
        } = options;

        const DeviceLog = Parse.Object.extend('DeviceLog');
        const query = new Parse.Query(DeviceLog);

        if (deviceId) {
            query.equalTo('deviceId', deviceId);
        }

        if (userId) {
            query.equalTo('userId', userId);
        }

        if (action) {
            query.equalTo('action', action);
        }

        const total = await query.count();
        query.skip((page - 1) * pageSize);
        query.limit(pageSize);
        query.descending('createdAt');

        const logs = await query.find();

        return {
            data: logs.map(log => ({
                id: log.id,
                deviceId: log.get('deviceId'),
                userId: log.get('userId'),
                action: log.get('action'),
                description: log.get('description'),
                createdAt: log.get('createdAt')
            })),
            total,
            page,
            pageSize,
            totalPages: Math.ceil(total / pageSize)
        };
    }
}

module.exports = DeviceService;
